﻿using System; 
using System.Collections.Generic;
using System.Linq; 
using System.Text;
using System.ServiceModel;
using System.Web.Mvc;
using System.ServiceModel.Web;
using System.Web.Http;
using System.Web.Security;
using System.Net.Http;

using ERPStore.Extensions;
using ERPStore.Web.Extensions;

using CloudSoft.Extensions;

namespace ERPStore.Web.Controllers
{
	[System.Web.Http.Description.ApiExplorerSettings(IgnoreApi = true)]
	public class AccountApiController : ApiController
	{
		public AccountApiController(ERPStore.Logging.ILogger logger
			, ERPStore.Services.IAccountService accountService
			, EventBrokR.IPublisher publisher)
		{
            this.AccountService = accountService;
			this.Logger = logger;
			this.Publisher = publisher;
		}

		protected ERPStore.Services.IAccountService AccountService { get; private set; }
		protected ERPStore.Logging.ILogger Logger { get; private set; }
		protected EventBrokR.IPublisher Publisher { get; private set; }

		protected virtual new ERPStore.Models.UserPrincipal User
		{
			get
			{
				return base.User as ERPStore.Models.UserPrincipal;
			}
		}

		[System.Web.Http.HttpGet]
		public DateTime Ping()
		{
			Logger.Debug("Calling Ping");
			return DateTime.Now;
		}

		public HttpResponseMessage PostAuthenticate([FromBody] Newtonsoft.Json.Linq.JObject json)
		{
			dynamic data = json;

			string userName = data.userName;
			string password = data.password;
			bool remember = data.remember;

			var response = Request.CreateResponse();

			if (userName.IsNullOrTrimmedEmpty()
				|| password.IsNullOrTrimmedEmpty())
			{
				response.Content = new StringContent("false");
				return response;
			}

			var userId = AccountService.Authenticate(userName, password);
			if (userId != 0)
			{
				var authenticatedCookie = ERPStore.Web.Extensions.HttpExtensions.CreateAuthenticatedCookie(userId, remember);
				response.Headers.AddCookies(new System.Net.Http.Headers.CookieHeaderValue[] { authenticatedCookie.ToCookieHeaderValue() });
				response.Content = new StringContent("true");
				Publisher.PublishAsync(new Events.UserAuthenticatedEvent()
				{
					UserId = userId,
					VisitorId = User.VisitorId,
				});

				return response;
			}
			else
			{
				Logger.Warn("logging fail with login : {0} pass : {1}", userName, password);
			}
			response.Content = new StringContent("false");
			return response;
		}

		[ActionFilters.ApiAuthorizedOperation]
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public ERPStore.Models.RegistrationListResult GetRegistrationList(ERPStore.Models.RegistrationListFilter filter)
		{
			Logger.Debug("Calling GetRegistrationList with filter : {0}", filter.SerializeToXml());
			return AccountService.GetRegistrationList(filter);
		}

		[ActionFilters.ApiAuthorizedOperation]
		[System.Web.Http.HttpGet]
		public ERPStore.Models.RegistrationUser GetByVisitorId(string Id)
		{
			Logger.Debug("Calling GetByVisitorId with VisitorId = {0}", Id);
			return AccountService.GetRegistrationUser(Id);
		}

		[ActionFilters.ApiAuthorizedOperation]
		[System.Web.Http.HttpPost]
		[System.Web.Http.HttpPut]
		public ERPStore.Models.RegistrationUser SaveRegistrationUser(ERPStore.Models.RegistrationUser registrationUser)
		{
			AccountService.SaveRegistrationUser(registrationUser.VisitorId, registrationUser);
			return registrationUser;
		}

		[ActionFilters.ApiAuthorizedOperation]
		[System.Web.Http.HttpGet]
		public ERPStore.Models.RegistrationUserConversionResult ConvertRegistrationUserToUser(int Id)
		{
			Logger.Debug("Calling ConvertRegistrationUserToUser with Id = {0}", Id);

			var result = new ERPStore.Models.RegistrationUserConversionResult();
			result.RegistrationUserId = Id;
			var registrationUser = AccountService.GetRegistrationUserById(Id);
			if (registrationUser == null)
			{
				result.ErrorMessage = "Inscription inéxistante";
				return result;
			}
			if (registrationUser.UserId.HasValue)
			{
				result.ConvertedUserId = registrationUser.UserId.Value;
				result.ErrorMessage = "Inscription déjà convertie";
				return result;
			}

			var ruleList = AccountService.ValidateRegistrationUser(registrationUser);
			if (!ruleList.IsNullOrEmpty())
			{
				result.BrokenRules = ruleList;
				result.ErrorMessage = "Conversion impossible";
				return result;
			}

			try
			{
				if (registrationUser.IsSameBillingAddress)
				{
					registrationUser.BillingAddressCity = registrationUser.ShippingAddressCity;
					registrationUser.BillingAddressCountryId = registrationUser.ShippingAddressCountryId;
					registrationUser.BillingAddressRecipientName = registrationUser.ShippingAddressRecipientName;
					registrationUser.BillingAddressRegion = registrationUser.ShippingAddressRegion;
					registrationUser.BillingAddressStreet = registrationUser.ShippingAddressStreet;
					registrationUser.BillingAddressZipCode = registrationUser.ShippingAddressZipCode;
				}

				using (var ts = TransactionHelper.GetNewReadCommitted())
				{
					var user = AccountService.RegisterUser(registrationUser);
					result.ConvertedUserId = user.Id;
					AccountService.CloseRegistrationUser(registrationUser.Id, user.Id);
					ts.Complete();
					Logger.Debug("UserConverted : {0}", user.Id);
				}
			}
			catch (ERPStore.Models.ValidationException vex)
			{
				result.ErrorMessage = "Echec de validation";
				result.BrokenRules = vex.List;
			}
			catch (Exception ex)
			{
				result.ErrorMessage = ex.Message;
				Logger.Debug("UserConversion error : {0}", ex.ToString());
			}

			return result;
		}

		[ActionFilters.ApiAuthorizedOperation]
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public List<ERPStore.Models.RegistrationUserConversionResult> ConvertRegistrationUserListToUser(List<int> registrationUserIdList)
		{
			Logger.Debug("Calling ConvertRegistrationUserListToUser with IdList = {0}", registrationUserIdList.SerializeToXml());

			if (registrationUserIdList == null)
			{
				throw new ArgumentException("registrationUserIdList does not be null");
			}
			if (registrationUserIdList.Count > 50)
			{
				throw new ArgumentException("registrationUserIdList items count less than 50");
			}
			var resultList = new List<ERPStore.Models.RegistrationUserConversionResult>();
			foreach (var id in registrationUserIdList)
			{
				var result = ConvertRegistrationUserToUser(id);
				resultList.Add(result);
			}
			return resultList;
		}

		public ViewModels.UserViewModel GetUserInfo()
		{
			if (User.CurrentUser != null)
			{
				var userVM = AutoMapper.Mapper.Map<ERPStore.Web.ViewModels.UserViewModel>(User.CurrentUser);
				userVM.IsAuthenticated = true;
				return userVM;
			}
			return new ViewModels.UserViewModel()
				{
					IsAuthenticated = false
				};
		}
	}
}
